'use strict';
const fs = require('fs');
const { URL } = require('url');
const Axios = require('axios');
const cheerio = require('cheerio');
const { JSDOM } = require('jsdom');
const dayjs = require('dayjs');
const querystring= require('querystring');
const tunnel = require('tunnel');


const userinfo = {
  username: 'geiniyomhbao',
  password: 'w82mqv68',
};

const nowstr = function() {
  return dayjs().format('YYYY-MM-DD HH:mm:ss');
};

const sleep = async function(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time);
  });
};

const url2responseurl = async function(url) {
  const Url = new URL(url);
  return `${Url.origin}${Url.pathname}${Url.search}`;
};

const http = async function(options = {}) {
  options.method = options.method || 'get';
  options.timeout = options.timeout || 120000;
  options.headers = options.headers || {};
  options.headers['Content-Type'] = options.headers['Content-Type'] || 'application/x-www-form-urlencoded; charset=UTF-8';
  return await Axios(options);
};


const getProxy = async function(loop = 2) {
  try {
    const proxy = await http({
      method: 'get',
      url: 'http://172.20.0.160:8090/util/proxy-invoke?site=tortious&min_exp=30&min_use=2',
      headers: {
        'util-app': 'tortious/ua5oSsl4vCEDxGVFA2BLrMctQ3zHXhZq',
      },
    });
    return proxy.data.data;
  } catch (e) {
    if (loop > 0) {
      return await getProxy(--loop);
    }
    throw e;
  }
};


function cyrb53(str, seed) {
  seed = seed || 0;
  let h1 = 0xdeadbeef ^ seed;
  let h2 = 0x8badf00d ^ seed;
  for (let i = 0, ch; i < str.length; i++) {
    ch = str.charCodeAt(i);
    h1 = Math.imul(h1 ^ ch, 2654435761);
    h2 = Math.imul(h2 ^ ch, 1597334677);
  }
  h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
  h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
  return (h2 >>> 0).toString(16) + (h1 >>> 0).toString(16);
}

function fswriter(file, string) {
  fs.writeFileSync(file, string);
}

const findQkByDoc = async function(dom_html) {
  const qk = dom_html.split('\n').filter(str => /qk/.test(str))[1];
  return /\"(?<qk>(.+))\"/.exec(qk).groups.qk;
};

const findFoByDoc = async function(dom_html) {
  const reg = /src="..\/scripts\/branddb-required.(\d+).min.js"/;   
  const fos = reg.exec(dom_html); 
  const fo = fos[1];
  return fo;
};

function getCookieValue(name, cookies) {
  for (const cookie of cookies) {
    if (cookie[name]) {
      return cookie[name];
    }
  }
  return null;
}

function getJosn(value, num) {
  return {
    p: {
      rows: value.p.rows,
      start: Number(value.p.start) + num * 100,
      sort: value.p.sort,
    },
    type: value.type,
    la: value.la,
    qi: value.qi,
    queue: value.queue,
    _: value._,
  };
}

async function myRandom(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min)
}

async function getUa(){
  const first_num = await myRandom(55, 62)
  const third_num = await myRandom(0, 3200)
  const fourth_num = await myRandom(0, 140)
  const os_type = [
    '(Windows NT 6.1; WOW64)', '(Windows NT 10.0; WOW64)', '(X11; Linux x86_64)',
    '(Macintosh; Intel Mac OS X 10_12_6)'
  ]
  const chrome_version = 'Chrome/'+first_num+'.0.'+third_num+'.'+fourth_num
  const uaList = ['Mozilla/5.0', os_type[Math.floor(Math.random()*os_type.length)], 'AppleWebKit/537.36', '(KHTML, like Gecko)', chrome_version, 'Safari/537.36']
  const ua = uaList.toString()
  return ua
}

async function initTunnelProxy() {
  const proxy = await getProxy();
  if (!proxy.ip || proxy.exp_time < (Date.now() - 120 * 1000)) {
    proxy = await getProxy();
  }
  return tunnel.httpsOverHttp({
    proxy: {
      host: proxy.ip,
      port: proxy.port,
      proxyAuth: `${proxy.user}:${proxy.pass}`,
    },
  });
}

async function saveDataStatus(repsarr, data) {
  var teInfor = {};
  var ctx = data.ctx
  var vals = data.vals
  var t = data.t
  var latestDate = data.latestDate
  var sour = repsarr.docs[0].SOURCE
  var nfd = repsarr.numFound
  var ups = Number(repsarr.start)
  teInfor.status = vals.status
  if(!t) {
    teInfor.startFrom = ups + repsarr.docs.length
    teInfor.totalNums = vals.totalNums
    if(latestDate) {
      teInfor.latestDate = latestDate
    }else{
      teInfor.latestDate = vals.latestDate
    }
    var oldVals = await ctx.app.redis.hget('tortious-config', sour);
    var oldSf = querystring.parse(oldVals).startFrom;
    if(oldSf < teInfor.startFrom) {
      await ctx.app.redis.hset('tortious-config', sour, querystring.stringify(teInfor));
    }
  }else {
    if(ups==0) {
      teInfor.startFrom = vals.startFrom
      teInfor.totalNums = nfd
      teInfor.latestDate = Date.parse(repsarr.docs[0].AD) - 28800000
      await ctx.app.redis.hset('tortious-config', sour, querystring.stringify(teInfor));
    }
  }
}


module.exports = {
  sleep,
  nowstr,
  fswriter,
  url2responseurl,
  http,
  getProxy,
  cyrb53,
  findQkByDoc,
  findFoByDoc,
  getCookieValue,
  getJosn,
  getUa,
  initTunnelProxy,
  saveDataStatus,
};
